import { Props } from "src/types/shape";
import utils from "src/utils";
import { idToRgba } from "src/utils/helper";
import Base from "./Base";

export enum BoxChild {
  line = 'line',
  base = 'base',
  top = 'top',
  right = 'right',
  bottom = 'bottom',
  left = 'left',
  scale = 'scale',
  topL = 'topL',
  topR = 'topR',
  bottomL = 'bottomL',
  bottomR = 'bottomR',
}
export const BoxChildList: Array<string> = [
  BoxChild.line,
  BoxChild.base,
  BoxChild.top,
  BoxChild.right,
  BoxChild.bottom,
  BoxChild.left,
  BoxChild.scale,
  BoxChild.topL,
  BoxChild.topR,
  BoxChild.bottomL,
  BoxChild.bottomR,
]
export default class extends Base {
  shapeMap: Map<string, string> = new Map()
  private readonly WIDTH = 15
  private readonly HEIGHT = 15
  private readonly borderColor = 'rgba(71, 154, 227, 1)'
  constructor(option: any) {
    super()
    utils.object.Assign(option, this.props)

    BoxChildList.forEach(item => {
      this.shapeMap.set(new Base().getRgbaId(), item)
    })
    this.selectable = false
  }
  handlePoints() {
    const { x, y, width } = this.props
    return [
      { x: x + width / 2, y: y - this.HEIGHT / 2 },
      { x: x + width / 2, y: y - this.HEIGHT * 2 + this.HEIGHT / 2 }
    ]
  }
  handleProps(type: string) {
    const { x, y, width, height } = this.props
    let _x = 0, _y = 0, _width = this.WIDTH, _height = this.HEIGHT
    switch (type) {
      case BoxChild.base:
        _x = x
        _y = y
        _width = width
        _height = height
        break
      case BoxChild.top:
        _x = x
        _y = y - height / 2
        break
      case BoxChild.bottom:
        _x = x
        _y = y + height / 2
        break
      case BoxChild.left:
        _x = x - width / 2
        _y = y
        break
      case BoxChild.right:
        _x = x + width / 2
        _y = y
        break
      case BoxChild.topL:
        _x = x - width / 2
        _y = y - height / 2
        break
      case BoxChild.topR:
        _x = x + width / 2
        _y = y - height / 2
        break
      case BoxChild.bottomL:
        _x = x - width / 2
        _y = y + height / 2
        break
      case BoxChild.bottomR:
        _x = x + width / 2
        _y = y + height / 2
        break
      case BoxChild.scale:
        _x = x
        _y = y - height / 2 - _height * 2
        break
    }
    return {
      x: type == BoxChild.base ? _x : _x + width / 2 - _width / 2,
      y: type == BoxChild.base ? _y : _y + height / 2 - _height / 2,
      width: _width,
      height: _height
    }
  }
  draw(ctx: CanvasRenderingContext2D, osCtx: OffscreenCanvasRenderingContext2D): void {
    ctx.save()

    this.transform(ctx)
    this.initOptions(ctx, 1)

    this.shapeMap.forEach((value, key) => {
      ctx.beginPath()
      if (value == BoxChild.line) {
        const pointList = this.handlePoints()
        ctx.lineTo(pointList[0].x, pointList[0].y)
        ctx.lineTo(pointList[1].x, pointList[1].y)
      } else {
        const { x, y, width, height } = this.handleProps(value)

        ctx.rect(x, y, width, height)
      }

      ctx.stroke()
      ctx.closePath()
    })


    ctx.restore()

    // 镜像画布

    osCtx.save()

    this.transform(osCtx)

    osCtx.beginPath()

    this.shapeMap.forEach((value, key) => {
      const [r, g, b, a] = idToRgba(key);

      osCtx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`
      osCtx.strokeStyle = `rgba(${r}, ${g}, ${b}, ${a})`      

      osCtx.beginPath()
      if (value == BoxChild.line) {
        const pointList = this.handlePoints()
        osCtx.lineTo(pointList[0].x, pointList[0].y)
        osCtx.lineTo(pointList[1].x, pointList[1].y)
      } else {
        const { x, y, width, height } = this.handleProps(value)

        osCtx.rect(x, y, width, height)
      }
      if (value == BoxChild.line || value == BoxChild.base) {
        osCtx.stroke()
      } else {
        osCtx.fill()
      }

      osCtx.closePath()
    })

    osCtx.restore()
  }
  setProps(option: Props): void {
    super.setProps(option)
    this.props.borderColor = this.borderColor

    this.props.width *= this.props.scaleX
    this.props.height *= this.props.scaleY
    this.props.scaleX = 1
    this.props.scaleY = 1
  }
}